package com.fy56.platform.logistics.restful.api.utils.weChat;

import com.fy56.platform.logistics.restful.api.utils.StringToConversionUtil;
import com.fy56.platform.logistics.utils.BeanTransitionShopUtil;
import com.fy56.platform.logistics.utils.HttpClientUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * [接入工具类]微信-公众号
 */
public class WeChatOfficialAccountUtil {

	private static Logger log = LoggerFactory.getLogger(WeChatOfficialAccountUtil.class);

	/*----------------------------------------------------------------------------------------------------*/

	/**
	 * 获取本机的外网IP
	 * @return
	 */
	public static String getV4IP(){
		String ip = "";

		StringBuilder inputLine = new StringBuilder();
		BufferedReader in = null;
		String read = "";
		try {
			URL url = new URL("http://ip.chinaz.com");
			HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
			in = new BufferedReader( new InputStreamReader(urlConnection.getInputStream(),"UTF-8"));
			while((read=in.readLine())!=null){
				inputLine.append(read+"\r\n");
			}
			//System.out.println(inputLine.toString());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(in!=null){
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			Pattern p = Pattern.compile("\\<dd class\\=\"fz24\">(.*?)\\<\\/dd>");
			Matcher m = p.matcher(inputLine.toString());
			if(m.find()){
				String ipstr = m.group(1);
				ip = ipstr;
				//System.out.println(ipstr);
			}
			return ip;
		}
	}

	/*----------------------------------------------------------------------------------------------------*/

	/**
     * [获取]微信access_token
     * @return
     * @throws Exception
     */
    public static String getAccessToken(String appid, String secret) throws Exception {
    	String action = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
    	String json = HttpClientUtils.get(action, null);
    	Map<String, Object> map = BeanTransitionShopUtil.jsonToMap(json);
    	return map.get("access_token") == null ? null : map.get("access_token").toString();
    }

    /*----------------------------------------------------------------------------------------------------*/

    /**
	 * [调用微信接口]获取_微信JS-SDK-签名凭证(jsapi_ticket)
	 * @param accessToken
	 * @return String
	 */
	public static String getJsApiTicket(String accessToken) throws Exception {
		String action = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";
		String json = HttpClientUtils.get(action, null);
    	Map<String, Object> map = BeanTransitionShopUtil.jsonToMap(json);
    	return map.get("ticket") == null ? null : map.get("ticket").toString();
	}

	/*----------------------------------------------------------------------------------------------------*/

	public static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

    /**
     * 微信JS-SDK_微信签名
     * @param jsapi_ticket (必填)微信JS-SDK-签名凭证
     * @param url (必填)鉴权页面地址
     * @return Map<String,String>
     */
    public static Map<String, String> sign(String jsapi_ticket, String url, String appid){
    	//使用https协议时，对http请求地址头进行过滤
    	url = url.replace("http:", "https:");

    	Map<String, String> ret = new HashMap<String, String>();

        String signature = "";
    	//[获取]时间戳
    	String timestamp = StringToConversionUtil.create_timestamp();
    	//[获取]字符串
    	String nonce_str = StringToConversionUtil.create_nonce_str();
    	String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url;
		System.out.println("==> string1:"+string1);
    	try {
    	    MessageDigest crypt = MessageDigest.getInstance("sha1");//SHA-1
    	    crypt.reset();
    	    crypt.update(string1.getBytes("UTF-8"));
    	    signature = byteToHex(crypt.digest());
    	} catch (NoSuchAlgorithmException e) {
    	    e.printStackTrace();
    	} catch (UnsupportedEncodingException e) {
    	    e.printStackTrace();
    	}

    	ret.put("url", url);
    	ret.put("appId", appid);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        return ret;
    }

    /*----------------------------------------------------------------------------------------------------*/

    /**
     * 返回openId
	 * @param appid 公众号 appId
	 * @param secret 公众号 secret
     * @param code
     * @return String
     */
    public static String getOpenId(String appid, String secret, String code) throws Exception {
		String action = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&code="+code+"&grant_type=authorization_code";
		String json = HttpClientUtils.get(action, null);
		Map<String, Object> map = BeanTransitionShopUtil.jsonToMap(json);
		log.info("===\tcode:"+code+"\t===>[获取]微信信息："+map);
		return map.get("openid") == null ? null : map.get("openid").toString();
    }

	/*----------------------------------------------------------------------------------------------------*/
    
    /**
     * [获取]微信UnionMap
     * @return
     * @throws Exception
     */
    public static Map<String, Object> getUserMap(String token, String openId) throws Exception {
    	String action = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+token+"&openid="+openId;
    	String jsonStr = HttpClientUtils.get(action, null);
    	Map<String, Object> map = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
    	return map;
    }
    
    /**
     * [获取]微信UnionId
     * @return
     * @throws Exception
     */
    public static String getUserUnionId(String token, String openId) throws Exception {
    	Map<String, Object> map = getUserMap(token, openId);
        return map.get("unionid") == null ? null : map.get("unionid").toString();
    }
    
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * [调用微信接口]发送提醒消息
	 * @param accessToken
	 * @param openid
	 * @param msg 内容
	 */
	public static void getMessage(String accessToken, String openid, String msg){
	    //获取请求路径
	    String action = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+accessToken;
		if(StringToConversionUtil.isNotNull(openid)){
			Map<String, Object> params = new HashMap<>();
			params.put("touser", openid);
			params.put("msgtype", "text");
			Map<String, Object> val = new HashMap<>();
			val.put("content", msg);
			params.put("text", val);
			try {
				String json = BeanTransitionShopUtil.ots(params);
				HttpClientUtils.postParameters(action, json);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * [调用微信接口]发送提醒消息(图文消息，点击跳转到外链)
	 * @param accessToken
	 * @param openid
	 * @param title 标题
	 * @param msg 内容
	 * @param url 跳转url
	 * @param picUrl 图片封面url
	 */
	public static void getMessageNews(String accessToken, String openid, String title, String msg, String url, String picUrl){
	    //获取请求路径
	    String action = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+accessToken;
		
	    log.info("openid:"+openid+", title:"+title+", msg:"+msg+", url:"+url+", picUrl:"+picUrl);
		
		HashMap<String, String> contentMap = new HashMap<>();
		if(StringToConversionUtil.isNotNull(title)){
			contentMap.put("title", title);
		}
		if(StringToConversionUtil.isNotNull(msg)){
			contentMap.put("description", msg);
		}
		if(StringToConversionUtil.isNotNull(url)){
			contentMap.put("url", url);
		}
		if(StringToConversionUtil.isNotNull(picUrl)){
			contentMap.put("picUrl", picUrl);
		}
		String json_content = BeanTransitionShopUtil.ots(contentMap);
		
		final String JSON_MODEL = "{\"touser\":\"TOUSER_0\", \"msgtype\":\"news\", \"news\":{\"articles\":[CONTENT_1]}}";
		if(StringToConversionUtil.isNotNull(openid)){
			String json = JSON_MODEL.replace("TOUSER_0", openid).replace("CONTENT_1", json_content);
			try {
				HttpClientUtils.postParameters(action, json);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * [调用微信接口]生成-公众号自定义推广码(二维码)
	 * @param accessToken
	 * @param sceneStr 自定义参数
	 * @param isTemporary 是否临时
	 * @param seconds 秒数
	 * @return
	 */
	public static Map<String, Object> establishCustomQRCode(String accessToken, String sceneStr, Boolean isTemporary, int seconds){
		//生成-公众号自定义推广码(二维码)
		Map<String, Object> retModel = new HashMap<String, Object>();
		//[获取]修改_微信卡券请求路径
		String action = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+accessToken;
		Map<String, Object> params = new HashMap<>();
		if(isTemporary){
			params.put("expire_seconds", seconds);//该二维码有效时间，以秒为单位。 最大不超过2592000（即30天），此字段如果不填，则默认有效期为30秒
			params.put("action_name", "QR_STR_SCENE");
			Map<String, Object> actionInfo = new HashMap<>();
			Map<String, Object> scene = new HashMap<>();
			scene.put("scene_str", sceneStr);
			actionInfo.put("scene", scene);
			params.put("action_info", actionInfo);
		}else{
			params.put("action_name", "QR_LIMIT_STR_SCENE");
			Map<String, Object> actionInfo = new HashMap<>();
			Map<String, Object> scene = new HashMap<>();
			scene.put("scene_str", sceneStr);
			actionInfo.put("scene", scene);
			params.put("action_info", actionInfo);
		}
		try {
			String c = BeanTransitionShopUtil.ots(params);
			System.out.println("### ===>>>\t传入json：" + c);
			String json = HttpClientUtils.postParameters(action, c);
			System.out.println("\n### ===>>>\t返回json：" + json);
			retModel = BeanTransitionShopUtil.jsonToMap(json);
			if(StringToConversionUtil.isNotNull(retModel.get("ticket").toString())){
				System.out.println("生成-公众号自定义推广码成功！");
			}else{
				System.out.println("生成-公众号自定义推广码失败！"+retModel.get("errmsg").toString());
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (ExecutionException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		}
		return retModel;
	}

}
